<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.0//EN" "http://www.wapforum.org/DTD/xhtml-mobile10.dtd">
<html>
  <head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=yes">
  
  
  <title>  Javascript 原型和原型链深度解析 |   写夜子的个人博客 </title>

 
  
    <link rel="icon" href="/images/favicon.png">
  


  <link rel="stylesheet" href="/nayo.min.css"> 
</head>  
  <body>   
    
      <header class="header">
	
  <nav class="header-nav">        
   
    <span class="iconfont icon-menu mobile-toggle"></span>   	

    <div class="header-menu">          
              
            
              <a class="header-menu-link" id="header-menu-home" href="/">首页</a>     
            
            
            
              <a class="header-menu-link" id="header-menu-archives" href="/archives">归档</a>     
            
            
            
              <a class="header-menu-link" id="header-menu-tags" href="/tags">标签</a>     
            
            
            
              <a class="header-menu-link" id="header-menu-about" href="/about">关于</a>     
            
            
            
              <a class="iconfont icon-menu-search header-menu-link" id="header-menu-search"></a>
            
                
    </div>  
    
  </nav>
</header>   

      <div class="container">       
          
          
            <section class="main">  
          

          <article class="post">
  
	<div class="post-header">

	<p class="post-title">	
		Javascript 原型和原型链深度解析
	</p>
			

	<div class="meta-info">	
	<span>
		11月 28, 2019
	</span>

	
	
		<i class="iconfont icon-words"></i>
		<span>
			6994
		</span>
	
</div>

</div> 
	 

	  <div class="post-content slideDownMin">

		

			
					<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>  在前端这块领域，原型与原型链是每一个前端er必须掌握的概念。我们多次在面试或者一些技术博客里面看见这个概念。由此可见，这个玩意对于前端来说有多重要。其实它本身理解起来不难，但是很多刚入行前端的同学，看到<code>prototype</code>、<code>__proto__</code>理解起来还是有点吃力，然后脑子里面就乱成一锅粥，就像我一样。但是这是很正常的事情，没什么大不了的，就像我们想要学会跑步，那么我们就必须先学会走路。任何事情都是有个过程的。所以现在就跟我一起来攻克这个难点吧。通过这篇文章你将掌握以下知识点:<a id="more"></a></p>
<ul>
<li>理解 <code>__proto_</code>;</li>
<li>理解 <code>prototype</code>;</li>
<li>理解<code>javascript</code>中<code>对象</code>的概念;</li>
<li>理解原型和原型链;</li>
<li>理解<code>javascript</code>中<code>类</code>的概念;</li>
<li>理解<code>new</code>的实现;</li>
<li>理解<code>instanceof</code>的实现;</li>
<li>理解<code>javascript</code>的继承;</li>
<li><p>加深对<code>javascript</code>这门语言的理解。        </p>
<p>这也是本篇文章的写作思路。</p>
</li>
</ul>
<h3 id="对象"><a href="#对象" class="headerlink" title="对象"></a><code>对象</code></h3><p>  那么我们就从对象这一概念开始说起，其实对象这一概念相信大家并不陌生。有一种说法是“javasrcript中万物皆是对象”，其实这个说法是错误的，一个很简单的例子，<code>javasript</code>中简单基本类型（string、boolean、number、null、undefined、symbol）本身就不是对象。其实<code>javasript</code>中对象主要分为<code>函数对象</code>和<code>普通对象</code>。其中:</p>
<ul>
<li><code>String</code></li>
<li><code>Number</code></li>
<li><code>Boolean</code></li>
<li><code>Object</code></li>
<li><code>Function</code></li>
<li><code>Array</code></li>
<li><code>Date</code></li>
<li><code>RegExp</code></li>
<li><p><code>Error</code></p>
<p>这些都是函数对象，他们同时也被称为<code>内置对象</code>。<code>函数对象</code>本身其实就是一个纯函数，<code>javascript</code>用他们来模拟<code>类</code>。普通对象就很简单了，就是我们常见的对象:</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> obj = &#123;</span><br><span class="line">    name: <span class="string">'juefei'</span>,</span><br><span class="line">    desc: <span class="string">'cool'</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>可能说到这，你还是无法理解到底啥是<code>函数对象</code>，啥是<code>普通对象</code>，那我们就一起来看看下面的代码:</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> obj1 = &#123;&#125;;</span><br><span class="line"><span class="keyword">const</span> obj2 = <span class="keyword">new</span> <span class="built_in">Object</span>();</span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">func1</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">const</span> obj3 = <span class="keyword">new</span> func1();</span><br><span class="line"><span class="keyword">const</span> func2 = <span class="keyword">new</span> <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">const</span> func3 = <span class="keyword">new</span> <span class="built_in">Function</span>()</span><br></pre></td></tr></table></figure>
<p>接着我们来分别打印一下他们:</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">console</span>.log(obj1);  <span class="comment">// object</span></span><br><span class="line"><span class="built_in">console</span>.log(obj2);  <span class="comment">// object</span></span><br><span class="line"><span class="built_in">console</span>.log(obj3);  <span class="comment">// object</span></span><br><span class="line"><span class="built_in">console</span>.log(func1);  <span class="comment">// function</span></span><br><span class="line"><span class="built_in">console</span>.log(func2);  <span class="comment">// function</span></span><br><span class="line"><span class="built_in">console</span>.log(func3);  <span class="comment">// function</span></span><br></pre></td></tr></table></figure>
<p>所以可以看见,<code>obj1</code>、<code>obj2</code>、,<code>obj3</code>是普通对象，他们都是<code>Object</code>的实例，而<code>func1</code>、<code>func2</code>、<code>func3</code>则都是<code>Function</code>的实例，称为<code>函数对象</code>。我们再看看:</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">console</span>.log(<span class="keyword">typeof</span> <span class="built_in">Object</span>);  <span class="comment">//f unction</span></span><br><span class="line"><span class="built_in">console</span>.log(<span class="keyword">typeof</span> <span class="built_in">Function</span>); <span class="comment">// function</span></span><br></pre></td></tr></table></figure>
<p>你是不是惊呆了，原来<code>Object</code>和<code>Function</code>都是 <code>Function</code>的实例。<br>所以我们得出一个结论就是：</p>
</li>
<li><p>只要是<code>Function</code>的实例，那就是<code>函数对象</code>，其余则为<code>普通对象</code>。 </p>
<p>同样我们也可以看出，不仅 <code>Object</code> 是<code>函数对象</code>,就连  <code>Function</code> 本身也是函数对象，因为我们通过 <code>console.log(typeof Function);</code> 得知 <code>Function</code> 是 <code>Function</code> 的实例。是不是又开始有点绕了？没事，到这一步你就记住我们刚刚的结论就算完成目标:</p>
</li>
<li><p>只要是<code>Function</code>的实例，那就是<code>函数对象</code>，其余则为<code>普通对象</code>。</p>
<p>那么说到对象，我们从上面可以看出，一个对象是通过构造函数 new 出来的，这其实跟<code>原型</code>和<code>原型链</code>有很大的关系，那么<code>原型</code>和<code>原型链</code>到底是用来干嘛的呢？</p>
<h3 id="原型"><a href="#原型" class="headerlink" title="原型"></a><code>原型</code></h3><p>涉及到这两个概念，我们就必须先来介绍两个东西: <code>__proto__</code> 和 <code>prototype</code> ，这两个变量可以说，在 <code>javascript</code> 这门语言里面随处可见，我们不管他三七二十一，我们先来看一张表:</p>
<p>| 对象类型 | <code>__proto__</code> | <code>prototype</code> |<br>| :—-:| :—-: | :—-: |<br>| 普通对象 | ✅ | ❌ |<br>| 函数对象 | ✅ | ✅ |</p>
</li>
</ul>
<p>   所以，请你先记住以下结论：</p>
<ul>
<li>只有<code>函数对象</code>有 <code>prototype</code> 属性，<code>普通对象</code> 没有这个属性。</li>
<li><p><code>函数对象</code> 和 <code>普通对象</code> 都有 <code>__proto__</code>这个属性。</p>
</li>
<li><p><code>prototype</code> 和  <code>__proto__</code>都是在创建一个函数或者对象会自动生成的属性。</p>
<p>接着我们来验证一下:</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">func</span> (<span class="params"></span>)</span>&#123;  <span class="comment">//func称为构造函数</span></span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"><span class="built_in">console</span>.log( <span class="keyword">typeof</span> func.prototype); <span class="comment">// object</span></span><br><span class="line"><span class="built_in">console</span>.log(<span class="keyword">typeof</span> func.__proto__);  <span class="comment">// function</span></span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> obj = &#123;&#125;</span><br><span class="line"><span class="built_in">console</span>.log(<span class="keyword">typeof</span> obj.__proto__) <span class="comment">//object</span></span><br><span class="line"><span class="built_in">console</span>.log(<span class="keyword">typeof</span> obj.prototype) <span class="comment">//undefined （看见了吧，普通对象真的没有 prototype 属性）</span></span><br></pre></td></tr></table></figure>
<p>所以就验证了我们刚刚的结论：</p>
</li>
<li>只有<code>函数对象</code>有 <code>prototype</code> 属性，<code>普通对象</code> 没有这个属性</li>
<li><code>函数对象</code> 和 <code>普通对象</code> 都有 <code>__proto__</code>这个属性。 </li>
<li><p><code>prototype</code> 和  <code>__proto__</code>都是在创建一个函数或者对象会自动生成的属性。</p>
<p>你看我又重复写了一遍，我不是为了凑字数，是为了你加深记忆，这对于我们接下来的篇幅很重要。<br>接着我们来看看下面的代码:</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">console</span>.log(obj.__proto__ === <span class="built_in">Object</span>.prototype); <span class="comment">// true</span></span><br><span class="line"><span class="built_in">console</span>.log(func.__proto__ === <span class="built_in">Function</span>.prototype); <span class="comment">// true</span></span><br></pre></td></tr></table></figure>
<p>所以我们又得出如下结论:</p>
</li>
<li>实例的 <code>__proto__</code>属性主动指向构造的 <code>prototype</code>;</li>
<li><code>prototype</code> 属性被 <code>__proto__</code> 属性 所指向。</li>
</ul>
<p>   这就是<code>prototype</code> 属性和 <code>__proto__</code> 属性的区别与联系。<br>   这可能又有点绕了，来多看几遍这一节，多背一下我们的结论。我们继续。<br>   那么问题来了，既然<code>func</code>是一个<code>函数对象</code>，函数对象是有 <code>prototype</code> 属性的，那么<code>func.prototype.__proto__</code>等于啥呢？<br>   为了解决这个问题，我们来思考一下：<br>   首先，我们看看<code>func.prototype</code> 是啥:<br>   <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">console</span>.log(<span class="keyword">typeof</span> func.prototype); <span class="comment">//object</span></span><br></pre></td></tr></table></figure></p>
<p>   好，我们知道了，<code>func.prototype</code>  是一个对象，那既然是对象，那 <code>func.prototype</code> 那不就是 <code>Object</code>的实例吗？那也就是说，<code>func.prototype.__proto__</code>属性肯定是指向 <code>Object.prototype</code> 咯！<br>   好，我们来验证一下:<br>   <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">console</span>.log(func.prototype.__proto__ === <span class="built_in">Object</span>.prototype); <span class="comment">//true</span></span><br></pre></td></tr></table></figure></p>
<p>   看见没有，就是这样的。那看到这里，我们应该也知道当我们这创建一个构造函数的时候，javascript是如何帮我们自动生成<code>__proto__</code>和<code>prototype</code>属性的。哈哈没错就是这样:<br>   <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//我们手动创建func函数</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">func</span>(<span class="params"></span>) </span>&#123;&#125;</span><br><span class="line"><span class="comment">//javascript悄悄咪咪执行以下代码:</span></span><br><span class="line">func._proto = <span class="built_in">Function</span>.prototype; <span class="comment">//实例的 __proto__ 属性主动指向构造的 prototype</span></span><br><span class="line">func.prototype = &#123;</span><br><span class="line">    <span class="keyword">constructor</span>: func,</span><br><span class="line">    __proto: Object.prototype //我们刚刚才在上面验证的，你别又忘记了</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>   我还专门为你画了个图(够贴心不老铁): </p>
<p>   <img src="https://user-gold-cdn.xitu.io/2019/11/14/16e65c6aa0d86971?w=1013&amp;h=749&amp;f=png&amp;s=23223" alt="原型.png"></p>
<p>   所以<code>prototype</code>又被称为显式原型对象，而<code>__proto__</code>又被称为隐式原型对象。</p>
<p>   hi，看到这里，你是不是有种脑子开了光的感觉。哈哈，所以到现在你应该已经理解原型的概念了，如果你还不理解，那就把上述章节再看一遍。最好拿个纸笔出来跟着画一画，顺便拿出电脑把示例代码敲一敲。好，整理一下头脑，接下来我们来看看什么又是<code>原型链</code>。</p>
<h3 id="原型链"><a href="#原型链" class="headerlink" title="原型链"></a><code>原型链</code></h3><p>   再介绍这个概念之前，我们先来看如下代码：<br>   <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Person</span> = <span class="title">function</span>(<span class="params">name,desc</span>)</span>&#123;</span><br><span class="line">    <span class="keyword">this</span>.name = name;</span><br><span class="line">    <span class="keyword">this</span>.desc = desc;</span><br><span class="line">&#125; <span class="comment">//***1****//</span></span><br><span class="line">Person.prototype.getName = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">this</span>.name;</span><br><span class="line">&#125;<span class="comment">//***2****//</span></span><br><span class="line">Person.prototype.getDesc = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">this</span>.desc;</span><br><span class="line">&#125;<span class="comment">//***3****//</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> obj = <span class="keyword">new</span> Person(<span class="string">'juefei'</span>,<span class="string">'cool'</span>);<span class="comment">//***4****//</span></span><br><span class="line"><span class="built_in">console</span>.log(obj);<span class="comment">//***5****//</span></span><br><span class="line"><span class="built_in">console</span>.log(obj.getName);<span class="comment">//***6****//</span></span><br></pre></td></tr></table></figure></p>
<p>   接下来我们来逐步解析一下:  </p>
<ol>
<li>创建了一个构造函数 <code>Person</code>，此时，<code>Person.portotype</code>自动创建，其中包含了 <code>constructor</code> 和 <code>__proto__</code>两个属性;</li>
<li>给对象 <code>Person.prototype</code> 新增了一个方法 <code>getName</code>;</li>
<li>给对象 <code>Person.prototype</code> 新增了一个方法 <code>getDesc</code>;</li>
<li>根据构造函数 <code>Person</code> 新建一个实例: <code>obj</code>（在创建实例的时候，构造函数会自动执行）;</li>
<li><p>打印实例 <code>obj</code> :</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">    name: <span class="string">'juefei'</span>,</span><br><span class="line">    desc: <span class="string">'cool'</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>根据上面一节的结论，我们得出：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">obj.__proto__ = Person.prototype;</span><br></pre></td></tr></table></figure>
</li>
<li><p>执行到第6步时，由于在实例 <code>obj</code> 上面找不到  <code>getName()</code>这个方法，所以它就会自动去通过自身的 <code>__proto__</code> 继续向上查找，结果找到了 <code>Person.prototype</code> ，接着它发现，刚好 <code>Person.prototype</code> 上面有<code>getName()</code>方法，于是找到了这个方法，它就停止了寻找。<br>怎么样，是不是有一种环环相扣的感觉？他们形成一个链了，没错，这就是<code>原型链</code>。</p>
</li>
</ol>
<p>  我们得出如下结论:<br>  在访问一个对象(假设这个对象叫obj)的属性/方法时，若在当前的对象上面找不到，则会尝试通过<code>obj.__proto__</code>去寻找，而 <code>obj.__proto__</code> 又指向其构造函数(假设叫<code>objCreated</code>)的 <code>prototype</code>，所以它又自动去 <code>objCreated.prototype</code> 的属性/方法上面去找,结果还是没找到，那么就访问 <code>objCreated.prototype.__proto__</code>继续往上面寻找，直到找到,则停止对原型链对寻找，若最终还是没能找到，则返回 <code>undefined</code> 。<br>  一直沿着原型链寻找下去，直到找到 <code>Object.prototype.__proto__</code>,指向 <code>null</code>，于是返回 <code>undefined</code>了。</p>
<p>  是不是自然而然就理解了。我又给你画了个图（请对照着上面👆那个图看）：</p>
<p>  <img src="https://user-gold-cdn.xitu.io/2019/11/14/16e65c6af86ce99f?w=740&amp;h=974&amp;f=png&amp;s=31405" alt="原型链.png"></p>
<p>  接下来我们再来增加一些概念：</p>
<ol>
<li>任何<code>内置函数对象</code>本身的 <code>__proto__</code>属性都指向 <code>Function</code>的原型对象，即： <code>Function.prototype</code>;</li>
<li><p>除了 <code>Object.prototype.__proto__</code>指向 <code>null</code> ,所有的<code>内置函数对象</code>的原型对象的 <code>__proto__</code>属性 ( <code>内置函数对象.prototype.__proto__</code>)，都指向<code>Object</code>。</p>
<p>我们得出如下终极原型链的图：<br><img src="https://user-gold-cdn.xitu.io/2019/11/14/16e65c6aa244de20?w=1183&amp;h=983&amp;f=png&amp;s=61470" alt="原型链终极图.png"></p>
<p>针对这个图，我最终给出我们经常看见那个原型链的图:</p>
</li>
</ol>
<p>  <img src="https://user-gold-cdn.xitu.io/2019/11/14/16e65c6aafce90b0?w=611&amp;h=760&amp;f=jpeg&amp;s=180716" alt="prototype.jpg"></p>
<p>  好好对比一下，拿出纸和笔画一画，根据上面章节的讲解，相信你很容易就能明白。</p>
<h3 id="javascript中的类"><a href="#javascript中的类" class="headerlink" title="javascript中的类"></a><code>javascript</code>中的<code>类</code></h3><p>  刚刚我们终于明白什么是 <code>原型</code> 和 <code>原型链</code>。下面我们根据上面的概念来讲解一下<code>javascript</code>中的<code>类</code>。<br>    我们知道，在面向对象的语言中，类可以被<code>实例化</code>多次，这个<code>实例化</code>是指我们可以根据构造函数去独立<code>复制</code>多个独立的实例，这些实例之间是独立的。但是实际上在 <code>javascript</code> 却不是这样的，因为它不是这种<code>复制机制</code>。我们不能创建一个类的多个实例，我们只能创建这个类的多个对象，因为他们都是通过<code>原型</code>和<code>原型链</code>关联到同一个对象。所以在 <code>javascript</code> 中 ,<code>类</code>都是通过<code>原型</code>和<code>原型链</code>来实现的，它其实是一种<code>委托方式</code>。</p>
<h3 id="new的实现"><a href="#new的实现" class="headerlink" title="new的实现"></a><code>new</code>的实现</h3><p>   了解了上面<code>javascript</code>中的<code>类</code>的概念，那我们应该很容易就理解<code>new</code>的过程，其核心无非就是执行原型链的链接:  </p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">myNew</span>(<span class="params">Cons,...args</span>)</span>&#123;</span><br><span class="line">    <span class="keyword">let</span> obj = &#123;&#125;;</span><br><span class="line">    obj.__proto__ = Cons.prototype; <span class="comment">//执行原型链接</span></span><br><span class="line">    <span class="keyword">let</span> res = Cons.call(obj,args);</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">typeof</span> res === <span class="string">'object'</span> ? res : obj;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="instanceof的实现"><a href="#instanceof的实现" class="headerlink" title="instanceof的实现"></a><code>instanceof</code>的实现</h3><p>  那么学习了<code>原型</code>和<code>原型链</code>，<code>instanceof</code>的实现肯定也很简单了，它也是通过<code>原型</code>和<code>原型链</code>来实现的:</p>
  <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">myInstanceof</span>(<span class="params">left,right</span>)</span>&#123;</span><br><span class="line">    <span class="keyword">let</span> rightProto = right.prototype;</span><br><span class="line">    <span class="keyword">let</span> leftValue = left.__proto__;</span><br><span class="line">    <span class="keyword">while</span>(<span class="literal">true</span>)&#123;</span><br><span class="line">        <span class="keyword">if</span>(leftValue === <span class="literal">null</span>)&#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span>(leftValue === rightProto)&#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        leftValue = leftValue.__proto__;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>   我就不讲解过程了，因为我知道你肯定能看懂，哈哈。</p>
<h3 id="javascript的继承"><a href="#javascript的继承" class="headerlink" title="javascript的继承"></a><code>javascript</code>的继承</h3><p>   我们都知道继承也是通过<code>原型</code>和<code>原型链</code>来实现的，那我在这里介绍两种常见的继承方式:</p>
<ol>
<li><p>组合继承:</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//组合式继承</span></span><br><span class="line"><span class="comment">//通过call继承Parent的属性，并传入参数</span></span><br><span class="line"><span class="comment">//将Child的原型对象指向Parent的实例，从而继承Parent的函数</span></span><br><span class="line"> <span class="function"><span class="keyword">function</span> <span class="title">Parent</span>(<span class="params">value</span>)</span>&#123;</span><br><span class="line">     <span class="keyword">this</span>.val = value;</span><br><span class="line"> &#125;</span><br><span class="line"> Parent.prototype.getValue = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">     <span class="built_in">console</span>.log(<span class="keyword">this</span>.val);</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="function"><span class="keyword">function</span> <span class="title">Child</span>(<span class="params">value</span>)</span>&#123;</span><br><span class="line">     Parent.call(<span class="keyword">this</span>,value);<span class="comment">//继承Parentd的属性</span></span><br><span class="line"> &#125;</span><br><span class="line"> Child.prototype = <span class="keyword">new</span> Parent();</span><br></pre></td></tr></table></figure>
<ol start="2">
<li>寄生组合式继承:</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//寄生组合式继承</span></span><br><span class="line"><span class="comment">//通过call继承Parent的属性，并传入参数</span></span><br><span class="line"><span class="comment">//通过Object.create()继承Parent的函数</span></span><br><span class="line">  <span class="function"><span class="keyword">function</span> <span class="title">Parent</span>(<span class="params">value</span>)</span>&#123;</span><br><span class="line">      <span class="keyword">this</span>.val = value;</span><br><span class="line">  &#125;</span><br><span class="line">  Parent.prototype.getValue = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">      <span class="built_in">console</span>.log(<span class="keyword">this</span>.val);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="function"><span class="keyword">function</span> <span class="title">Child</span>(<span class="params">value</span>)</span>&#123;</span><br><span class="line">      <span class="comment">//继承Parentd的属性</span></span><br><span class="line">      Parent.call(<span class="keyword">this</span>,value);</span><br><span class="line">  &#125;</span><br><span class="line">  Child.prototype = <span class="built_in">Object</span>.create(Parent.prototype,&#123;</span><br><span class="line">      <span class="keyword">constructor</span>:&#123;</span><br><span class="line">          value:Child,</span><br><span class="line">          writable:<span class="literal">true</span>,</span><br><span class="line">          configurable:<span class="literal">true</span>,</span><br><span class="line">          enumerable:<span class="literal">false</span></span><br><span class="line">      &#125;</span><br><span class="line">  &#125;)</span><br></pre></td></tr></table></figure>
<h3 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h3></li>
<li><p>若 A 通过 new 创建了 B,则 <code>B.__proto__ = A.prototype</code>；</p>
</li>
<li>执行<code>B.a</code>，若在B中找不到a，则会在<code>B.__proto__</code>中，也就是<code>A.prototype</code>中查找，若<code>A.prototype</code>中仍然没有，则会继续向上查找，最终，一定会找到<code>Object.prototype</code>,倘若还找不到，因为<code>Object.prototype.__proto__</code>指向<code>null</code>，因此会返回<code>undefined</code>；</li>
<li>原型链的顶端，一定有 <code>Object.prototype.__proto__</code> ——&gt; null。</li>
</ol>
<p>由此可见，<code>原型</code>和<code>原型链</code>是如此的强大，希望看完这篇文章，你不再会对他们感到恐惧。<br>   写完这篇已经近凌晨两点，如果你觉得这篇文章对你有些许收获，请点赞支持！！</p>
<p>   参考资料:<br>   &lt;&lt; 你不知道的javascript 上卷 &gt;&gt;</p>
  	
					
	  </div>     
	  

	
<div class="post-meta">
      	

      
        <i class="iconfont icon-tag"></i>     
          <a class="tag-link" href="/tags/ES6/">ES6</a> <a class="tag-link" href="/tags/Javascript/">Javascript</a>    
      	
</div>





<div class="post-footer">
  <div class="pf-left">
      <img class="pf-avatar" src="http://wx2.sinaimg.cn/mw690/89296167gy1fu5ph67x17j21kw1kwhdu.jpg">
      <p class="pf-des">hi,我是写夜子,希望你有愉快的一天.</p>
  </div>

  <div class="pf-right">           
      <div class="pf-links">
        




<span class="donate-btn">
	<span class="iconfont icon-donate"></span>
</span>


<div id="donate-box" class="sildeUpMin">

	<span class="donate-cancel iconfont icon-cancel"></span>

	<div class="donate-img-box">
		<img id="donate-qr-wechat" class="noLazyLoad donate-img lazyload" src="/images/placeholder.png" alt="No Donate Image!" data-src="/images/donate1.png">	
		<img id="donate-qr-alipay" class="noLazyLoad donate-img lazyload" src="/images/placeholder.png" alt="No Donate Image!" data-src="/images/donate2.png">	
	</div>

	<span class="donate-word">世界美好 你也是</span>

	<div class="donate-list">
		<span class="iconfont icon-donate-wechat"></span>
		<span class="iconfont icon-donate-alipay"></span>
	</div>

</div>

 
        
	
<script id="-mob-share" src="http://f1.webshare.mob.com/code/mob-share.js?appkey=21d601593a1de"></script>
	
	<span class="share-btn">
	<span class="iconfont icon-share"></span>
	</span>


	<div class="-mob-share sildeUpMin">
		   			             
            <a class="iconfont  icon-share-qq -mob-share-qq"></a>		
     	   			             
            <a class="iconfont  icon-share-weixin -mob-share-weixin"></a>		
     	   			             
            <a class="iconfont  icon-share-weibo -mob-share-weibo"></a>		
     	   			             
            <a class="iconfont  icon-share-douban -mob-share-douban"></a>		
     	   			             
            <a class="iconfont  icon-share-facebook -mob-share-facebook"></a>		
     	   			             
            <a class="iconfont  icon-share-twitter -mob-share-twitter"></a>		
     	   			             
            <a class="iconfont  icon-share-google -mob-share-google"></a>		
     	   
	</div>	

      </div>  
    <nav class="pf-paginator">
      
         
          <a href="/2019/11/29/React基础入门/" data-hover="React基础入门">上一篇</a>      
            
        
      
        
        <a href="/2019/11/05/JavaScript的一些闲散的代码块/" data-hover="JavaScript的一些闲散的代码块"> 下一篇</a>
            
  </nav>   
  </div>
</div> 
	
	
</article>

          </section> 
      </div>            
    
    <a id="backTop">
      <span>
        <i class="iconfont icon-backtotop"></i>
      </span>
    </a> 

  
    
    <div class="search-container sildeUpMin">
        <div class="search-header">
            <input type="text" placeholder="输入你想搜索的" id="search-input" class="search-input">  
            <span class="search-cancel iconfont icon-cancel"></span>
        </div>
        <div id="search-result" class="search-result"></div>
    </div>
 
     <div class="mobile-menu">      

      
      <img class="mobile-menu-icon lazyload" src="/images/placeholder.png" data-src="/images/favicon.png">   
      

         
            

            <a class="mobile-menu-link" href="/">首页
            </a>
            
         
            

            <a class="mobile-menu-link" href="/archives">归档
            </a>
            
         
            

            <a class="mobile-menu-link" href="/tags">标签
            </a>
            
         
            

            <a class="mobile-menu-link" href="/about">关于
            </a>
            
         
                          

            <a class="mobile-menu-link mobile-menu-search" href="#">搜索 </a>                 
            
         
      
</div>        
    


<script>
var _hmt = _hmt || [];
(function() {
  var hm = document.createElement("script");
  hm.src = "https://hm.baidu.com/hm.js?636802045446222199ae541e32c8133e"; 
  var s = document.getElementsByTagName("script")[0]; 
  s.parentNode.insertBefore(hm, s);
})();
</script>





     
    




<footer id="footer">


		<div class="footer-copyright">
		&copy;
		
		2018-
		
		2020

		Xieyezi
		<br>

		Copyright
		<a href="https://github.com/xieyezi" target="_blank">Xieyezi</a>
		</div>

</footer>
   

  

    <script src="/nayo.bundle.js"></script>           
  </body>        
</html>